package com.ruoyi.factory.receipt.service.impl;

import com.ruoyi.factory.common.utils.IdGen;
import com.ruoyi.factory.qylock.domain.EreceiptHead;
import com.ruoyi.factory.qylock.mapper.EreceiptHeadMapper;
import com.ruoyi.factory.qylock.utils.OkHttpUtils;
import com.ruoyi.factory.receipt.service.ReceiptService;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import okhttp3.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;

import java.io.*;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ReceiptServiceImpl implements ReceiptService {

    @Autowired
    private EreceiptHeadMapper ereceiptHeadMapper;

    protected final Logger logger = LoggerFactory.getLogger(ReceiptServiceImpl.class);

    public JSONObject elerecordbyreceipt (JSONObject param){
        logger.info("电子收据集成电子档案回调入参: "+param.toString());
        //1.接收电子档案信息 2.查询电子收据信息 3.将文件归档
        String type = param.optString("type");
        //会计年
        String accountYear = param.optString("accountYear");
        //会计月
        String accountMonth = param.optString("accountMonth");
        String range = param.optString("range");
        String showUpper = param.optString("showUpper");
        //采集任务编码，长度限制500
        String taskId = param.optString("taskId");
        //档案回调地址
        String callbackUrl = param.optString("callbackUrl");
        //组织信息
        JSONObject orgInfoObject = param.optJSONObject("orgInfo");
        String pk = orgInfoObject.optString("pk");
        String otype = orgInfoObject.optString("type");
        String code = orgInfoObject.optString("code");

        JSONObject fileServerObject = param.optJSONObject("fileServer");
        String endpoint = fileServerObject.optString("endpoint");
        String accessKey = fileServerObject.optString("accessKey");
        String secretKey = fileServerObject.optString("secretKey");
        String serverType = fileServerObject.optString("serverType");
        String bucketName = fileServerObject.optString("bucketName");

        String period = param.optString("period");
        String periodIndex = param.optString("periodIndex");
        String srcSys = param.optString("srcSys");

        JSONArray docPkList = param.optJSONArray("docPkList");
        //根据编号查询单据,根据单号查询信息,根据信息查询文件
        String[] params = new String[docPkList.size()];
        for (int i = 0; i < docPkList.size(); i++) {
            String s = (String)docPkList.get(i);
            params[i] = s;
        }
        //根据参数查询数据
        List<EreceiptHead> ereceiptHeads = ereceiptHeadMapper.selectEreceiptHeadByIds(params);
        //封装单条请求信息
        //将文件信息返回先出
        JSONObject paramObject = new JSONObject();

        paramObject.put(srcSys,"IDOC");
        paramObject.put("status",200);
        paramObject.put("taskId",taskId);
        paramObject.put("totalCount",ereceiptHeads.size());
        JSONArray docListArray = new JSONArray();
        for (EreceiptHead ereceiptHead : ereceiptHeads) {
            String contractId = ereceiptHead.getContractId();
            try {
                int esignFileDown = getEsignFileDown(contractId);
                JSONObject orgInfoObject2 = new JSONObject();
                orgInfoObject2.put("code","1001-0001#YonBIp");
                orgInfoObject2.put("pk","1001A110000000002LHC");
                JSONObject descDataObject = new JSONObject();
                descDataObject.put("orgInfo",orgInfoObject2);
                descDataObject.put("keywords","电子收据");
                descDataObject.put("abstracts","电子收据");
                descDataObject.put("title","电子收据");
                descDataObject.put("accountMonth",accountMonth);
                descDataObject.put("accountYear",accountYear);
                descDataObject.put("childrenAnnexCount",1);
                descDataObject.put("childrenCount",1);
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
                Date date = new Date();
                String format = sdf.format(date);
                String format1 = sdf2.format(date);
                descDataObject.put("docDate",format1);
                descDataObject.put("docType","receipt");
                descDataObject.put("fileNo", IdGen.uuid());
//                descDataObject.put("fileSize",esignFileDown);
                descDataObject.put("fileUrl","thirdsysuploader/receipt/"+contractId+".pdf");
                descDataObject.put("pages",1);
                descDataObject.put("pk",ereceiptHead.getCode());
                descDataObject.put("srcFileName",contractId+".pdf");
                descDataObject.put("storeType",2);
                descDataObject.put("ts",format);
                JSONObject sysInfo = new JSONObject();
                sysInfo.put("sysVersion","1");
                sysInfo.put("sysName","receipt");
                sysInfo.put("developerName","ruifeng");
                descDataObject.put("sysInfo",sysInfo);
                JSONObject doc = new JSONObject();
                doc.put("descData",descDataObject);
                docListArray.add(doc);
            } catch (Exception e) {
                logger.info(e.getMessage());
            }
            paramObject.put("docList",docListArray);
            logger.info("请求电子收据集成电子档案确认数据url: "+ callbackUrl);
            logger.info("请求电子收据集成电子档案确认数据入参: "+ paramObject.toString());
            String s = OkHttpUtils.okHttpPost(callbackUrl, paramObject.toString());
            logger.info("请求电子收据集成电子档案确认数据返参: "+ s);
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("msg","success");
        jsonObject.put("code","0000");
        return jsonObject;
    }




    public int getEsignFileDown(String contractId) throws Exception {

        // 请求契约锁需要的参数
        String url = "/contract/download";

        Map<String,String> param = new HashMap<>();
        param.put("contractId", contractId);
        param.put("downloadItems", "NORMAL");
        param.put("needCompressForOneFile", "false");
        Response responses = OkHttpUtils.okHttpGetqysxz(url, param);
        InputStream ins = null;
        if(responses.code() != 200) logger.info("电子签章下载失败");
        ins = responses.body().byteStream();

        // 创建临时文件
        File tempFile = File.createTempFile("temp-", ".tmp");
        tempFile.deleteOnExit();
        try (FileOutputStream fos = new FileOutputStream(tempFile)) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = ins.read(buffer)) != -1) {
                fos.write(buffer, 0, bytesRead);
            }
        }catch (Exception e){
            logger.info(e.getMessage());
        }
        FileInputStream fileInputStream = new FileInputStream(tempFile);
        uploadSftpLoadFile(contractId, fileInputStream);
        return fileInputStream.available();
    }
    //文件上传
    public void uploadSftpLoadFile(String contractId, FileInputStream fis){
        String host = "192.168.0.42";
        int port = 22;
        String user = "thirdsysuploader";
        String password = "qwe123!@#";
//        String localFile = "D:/test/upload.txt";
        String rootPath = "/data/iuap/middleware/nginx/html/FSClient/storage/static/defbucket/";
        /**
         * 税务系统下面的文件设置为tax,票据系统设置为receipt,费控设置为costCtl
         * 如果是收据该值为thirdsysuploader/receipt，如果是费用控制该值为thirdsysuploader/costCtl
         */
        String relativePath ="thirdsysuploader/receipt/";
        String fileName = contractId+".pdf";
        String remoteDir = rootPath + relativePath;
        //封装推送中台数据时使用的文件上传路径；
        String uploadRelativePath = relativePath+fileName;
        uploadFile(host, port, user, password, remoteDir, fileName,fis );
    }

    private void mkdirs(ChannelSftp sftp, String path) throws SftpException {
        String[] folders = path.split("/");
        String current = "";
        for (String folder : folders) {
            if (folder.isEmpty()){
                continue;
            }
            current += "/" + folder;
            try {
                sftp.cd(current);
            } catch (SftpException e) {
                sftp.mkdir(current);
            }
        }
    }

    //创建文件上传的方法
    public void uploadFile(String host, int port,
                                  String user, String password,
                                  String remoteDir, String fileName, FileInputStream fis) {

        ChannelSftp sftp = null;
        Session session = null;
        FileInputStream fileInputStream = null;
        try {
            JSch jsch = new JSch();
            session = jsch.getSession(user, host, port);
            session.setPassword(password);
            session.setConfig("StrictHostKeyChecking", "no");
            session.setTimeout(20000);
            session.connect();

            sftp = (ChannelSftp) session.openChannel("sftp");
            sftp.connect();

            mkdirs(sftp, remoteDir);  // 递归创建目录
            sftp.cd(remoteDir);
//            fileInputStream = new FileInputStream(filePath);
            sftp.put(fis, fileName);
        } catch (Exception e) {
            //TODO文件上传失败
            e.printStackTrace();
        }finally {
            try {
                sftp.disconnect();
            } catch (Exception e) {
            }
            try {
                session.disconnect();
            } catch (Exception e) {

            }
//            try {
//                fileInputStream.close();
//            } catch (IOException e) {
//
//            }
        }
    }
}
